0x00 前言
Hbase全称为Hadoop Database,是一个分布式的存储系统。Hbase使用Hadoop的HDFS作为其文件存储系统,使用Hadoop的MapReduce来处理Hbase中的海量数据,使用zookeeper作为其协调工具。
查看本教程之前,请确保已安装配置好Hadoop,可参考Centos7搭建Hadoop伪分布式集群详细步骤,使用Hadoop JAVA API 远程连接HDFS
0x01 下载安装
下载
首先在官网下载Hbase
选择对应版本的bin文件,国内根据推荐的清华源下载即可。
linux下可使用wget
命令下载,我下载的为2.1.4
版本1
wget http://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.1.4/hbase-2.1.4-bin.tar.gz
解压
下载后即可解压到目录,我这里直接在当前目录解压1
tar -zxvf hbase-2.1.4-bin.tar.gz
配置环境变量
进入解压后的目录使用pwd
命令查看路径
然后修改.bashrc
配置环境变量
1 | vi ~/.bashrc |
然后使用source ~/.bashrc
命令使配置生效
然后输入命令hbase
可看到环境变量配置成功
0x02 启动Hbase
在启动hbase之前。首先进行相应的配置修改
配置hbase-env.sh
修改hbase所在目录下的conf
目录的hbase-env.sh
如我的位置为/home/wzb/hbase-2.1.4/conf/hbase-env.sh
首先配置环境变量export JAVA_HOME=/usr/local/java/jdk1.8.0_201
,此处修改为你的java环境变量,如不知道,可通过echo $JAVA_HOME
查看
然后配置export HBASE_MANAGES_ZK=true
,使用其自带的zookeeper
配置hbase-site.xml
然后继续配置conf
目录下的hbase-site.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://192.168.111.147:9000/hbase</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>192.168.111.147</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value> wzb/Hbase tmp</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
</configuration>
注意标识处根据自己环境修改
下载htrace-core-3.1.0-incubating.jar
下载htrace-core-3.1.0-incubating.jar并移至hbase安装目录下的lib
文件夹
启动start-hbase.sh
配置修改好后即可通过start-hbase.sh
命令启动
在启动之前,请先使用start-all.sh
启动hadoop相关进程
然后即可使用命令start-hbase.sh
启动hbase
通过jps
可看到比刚才多出来HMaster
HRegionServer
HQuorumPeer
三个进程,如后面出现错误可看查这些进程是否正常启动,如未启动移步文章末尾问题解决可查笔者记录的解决办法。
访问apache Hbase
此处正常启动后继续
然后通过浏览器访问http://192.168.111.147:16010/master-status
此处ip即为你在hbase-site.xml
文件中配置的ip
至此Hbase启动成功。
0x03 Hbase shell
hbase提供了一个shell的终端给用户交互。使用命令hbase shell
进入命令界面。通过执行 help可以看到命令的帮助信息。
下图列出常用命令
更过命令操作可参考HBase shell 命令介绍
0x04 Java API连接Hbase
修改hosts
因为Hbase 16000端口绑定为127.0.0.1,所以通过其他主机无法访问,这里唯一的解决方法是修改hosts文件
修改linux hostnamesudo vi /etc/sysconfig/network
添加以下内容1
2NETWORKING=yes
HOSTNAME=master
修改linux hostssu vi /etc/hosts
添加以下内容
1 | 192.168.111.147 master #此处ip添加你的linux ip,hostname填写上面修改的,我这里设置为master。 |
linux配置完成后需重启系统,以使配置生效。
修改windows hosts文件
路径为:C:\Windows\System32\drivers\etc\hosts
该文件无权限直接修改,需复制出修改完再覆盖掉
最后添加一行192.168.111.147 master
,同样此处应与上面相同。
配置完成后即可继续下面使用java api连接,不配置可能会导致无法连接。
JAVA API
关于java项目创建参见使用Hadoop JAVA API 远程连接HDFS
在pom.xml
中添加1
2
3
4
5<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.4</version>
</dependency>
将Hbase-site.xml
添加到项目中,如下图
新建HBase
类,内容如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package hadoop;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
public class HBase {
public static Configuration conf;
public static Connection connection;
public static Admin admin;
public static void main(String[] args) throws IOException {
conf = HBaseConfiguration.create();
conf.set("hbase.master", "192.168.111.147:16000");
connection = ConnectionFactory.createConnection(conf);
admin = connection.getAdmin();
HTableDescriptor table = new HTableDescriptor(TableName.valueOf("table1"));
table.addFamily(new HColumnDescriptor("group1")); //创建表时至少加入一个列组
if(admin.tableExists(table.getTableName())){
admin.disableTable(table.getTableName());
admin.deleteTable(table.getTableName());
}
admin.createTable(table);
}
}
运行成功后成功创建table1
表
转到Hbase shell使用list命令可看到新表已创建
详细代码
将常用hbase api封装好了,直接在main函数中调用即可。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203package hadoop;
import java.io.File;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
public class HbaseTest {
public static Configuration configuration;
public static Connection connection;
public static Admin admin;
public static void main(String[] args) throws IOException {
//createTable("t2", new String[] { "cf1", "cf2" });
listTables();
/*
* insterRow("t2", "rw1", "cf1", "q1", "val1"); getData("t2", "rw1",
* "cf1", "q1"); scanData("t2", "rw1", "rw2");
* deleRow("t2","rw1","cf1","q1"); deleteTable("t2");
*/
}
// 初始化链接
public static void init() {
configuration = HBaseConfiguration.create();
/*
* configuration.set("hbase.zookeeper.quorum",
* "10.10.3.181,10.10.3.182,10.10.3.183");
* configuration.set("hbase.zookeeper.property.clientPort","2181");
* configuration.set("zookeeper.znode.parent","/hbase");
*/
//configuration.set("hbase.zookeeper.property.clientPort", "2181");
//configuration.set("hbase.zookeeper.quorum", "192.168.111.151");
configuration.set("hbase.master", "192.168.111.151:16000");
File workaround = new File(".");
System.getProperties().put("hadoop.home.dir",
workaround.getAbsolutePath());
new File("./bin").mkdirs();
try {
new File("./bin/test").createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
} catch (IOException e) {
e.printStackTrace();
}
}
// 关闭连接
public static void close() {
try {
if (null != admin)
admin.close();
if (null != connection)
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 建表
public static void createTable(String tableNmae, String[] cols) throws IOException {
init();
TableName tableName = TableName.valueOf(tableNmae);
if (admin.tableExists(tableName)) {
System.out.println("talbe is exists!");
} else {
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
for (String col : cols) {
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(col);
hTableDescriptor.addFamily(hColumnDescriptor);
}
admin.createTable(hTableDescriptor);
}
close();
}
// 删表
public static void deleteTable(String tableName) throws IOException {
init();
TableName tn = TableName.valueOf(tableName);
if (admin.tableExists(tn)) {
admin.disableTable(tn);
admin.deleteTable(tn);
}
close();
}
// 查看已有表
public static void listTables() throws IOException {
init();
HTableDescriptor hTableDescriptors[] = admin.listTables();
for (HTableDescriptor hTableDescriptor : hTableDescriptors) {
System.out.println(hTableDescriptor.getNameAsString());
}
close();
}
// 插入数据
public static void insterRow(String tableName, String rowkey, String colFamily, String col, String val)
throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(val));
table.put(put);
// 批量插入
/*
* List<Put> putList = new ArrayList<Put>(); puts.add(put);
* table.put(putList);
*/
table.close();
close();
}
// 删除数据
public static void deleRow(String tableName, String rowkey, String colFamily, String col) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowkey));
// 删除指定列族
// delete.addFamily(Bytes.toBytes(colFamily));
// 删除指定列
// delete.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
table.delete(delete);
// 批量删除
/*
* List<Delete> deleteList = new ArrayList<Delete>();
* deleteList.add(delete); table.delete(deleteList);
*/
table.close();
close();
}
// 根据rowkey查找数据
public static void getData(String tableName, String rowkey, String colFamily, String col) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowkey));
// 获取指定列族数据
// get.addFamily(Bytes.toBytes(colFamily));
// 获取指定列数据
// get.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
Result result = table.get(get);
showCell(result);
table.close();
close();
}
// 格式化输出
public static void showCell(Result result) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println("RowName:" + new String(CellUtil.cloneRow(cell)) + " ");
System.out.println("Timetamp:" + cell.getTimestamp() + " ");
System.out.println("column Family:" + new String(CellUtil.cloneFamily(cell)) + " ");
System.out.println("row Name:" + new String(CellUtil.cloneQualifier(cell)) + " ");
System.out.println("value:" + new String(CellUtil.cloneValue(cell)) + " ");
}
}
// 批量查找数据
public static void scanData(String tableName, String startRow, String stopRow) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
// scan.setStartRow(Bytes.toBytes(startRow));
// scan.setStopRow(Bytes.toBytes(stopRow));
ResultScanner resultScanner = table.getScanner(scan);
for (Result result : resultScanner) {
showCell(result);
}
table.close();
close();
}
}
0x05 问题解决
此处容易出现的问题为HMaster
启动后闪退。
可通过查看hbase安装目录下的logs
文件内log日志确定该问题。
HDFS问题
首先查看hbase-wzb-master-wzb_node1.log
,此处查看你的master
日志文件
发现9000的HDFS连接失败
首先浏览器访问你的ip的9000端口,即hdfs
服务,访问成功如下图
如果未访问成功,查看hadoop配置文件core-site.xml
查看hdfs是否正确配置为你的ip,不是请修改,确保hbase配置文件中连接的hdfs服务器与你启动的服务器路径相同。
配置成功后重启hadoop,再次访问
权限问题
同样查看日志问题,如发现前面配置的Hbase文件夹有权限问题,请将Hbase文件夹赋予777权限1
chomd 777 Hbase //此处Hbase请添加你hbase-site.xml中配置的hbase.zookeeper.property.dataDir目录
zookeeper未正常启动问题
查看hbase-wzb-regionserver-wzb_node1.log
此处应修改为你的regionserve
log文件
出现以下错误说明zookeeper
未启动成功。
首先查看sudo netstat -anp | grep 2181
端口是否被占用,如果占用,找到占用程序并kill掉相关进程。
防火墙问题
如果出现其他端口无法访问问题,请关闭防火墙1
2
3systemctl stop firewalld.service
systemctl disable firewalld.service
其他问题
配置过程中可能出现其他各种问题,可查看log文件出现的问题并解决。